package com.gzsxy.esjy.pool;

import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.RejectedExecutionException;

/**
 *  LinkedTransferQueue 能保证更高性能，相比与LinkedBlockingQueue有明显提升
 *          不过LinkedTransferQueue的缺点是没有队列长度控制，需要在外层协助控制
 * @author zhangxiaolong
 * @date 2022/7/6 9:36
 */
public class ExecutorQueue extends LinkedTransferQueue<Runnable> {

    private static final long serialVersionUID = -265236426751004839L;

    private StandardThreadExecutor threadPoolExecutor;

    public ExecutorQueue() {
        super();
    }

    public void setStandardThreadExecutor(StandardThreadExecutor threadPoolExecutor) {
        this.threadPoolExecutor = threadPoolExecutor;
    }

    public boolean force(Runnable o) {
        //shutdown 或者 shutdownNow 来关闭线程池，两个方法有一个被调用，isShutdown() 方法就会返回 true
        //shutdown 当线程池调用该方法时,线程池的状态则立刻变成SHUTDOWN状态。此时，则不能再往线程池中添加任何任务，
        //  * 否则将会抛出RejectedExecutionException异常。
        //  * 但是，此时线程池不会立刻退出，直到添加到线程池中的任务都已经处理完成，才会退出。
        //ShutdownNow()并不代表线程池就一定立即就能退出，它可能必须要等待所有正在执行的任务都执行完成了才能退 出
        if (threadPoolExecutor.isShutdown()) {
            throw new RejectedExecutionException("Executor not running, can't force a command into the queue");
        }
        return super.offer(o);
    }

    @Override
    public boolean offer(Runnable o) {
        int poolSize = threadPoolExecutor.getPoolSize();

        if (poolSize == threadPoolExecutor.getMaximumPoolSize()) {
            return super.offer(o);
        }

        if (poolSize >= threadPoolExecutor.getSubmittedTasksCount()) {
            return super.offer(o);
        }

        if (poolSize < threadPoolExecutor.getMaximumPoolSize()) {
            return false;
        }

        return super.offer(o);
    }

}
